//!
//! Copyright (c) 2024-2999 北京心月狐科技有限公司 All rights reserved.
//!
//! https://www.mxxshop.com
//!
//! Licensed 并不是自由软件，未经许可不能去掉 MxxShop 相关版权
//!
//! 版权所有，侵权必究！
//!

use std::sync::LazyLock;
use actix_cors::Cors;
use actix_http::header;
use actix_session::{SessionMiddleware};
use actix_session::config::BrowserSession;
use actix_session::storage::CookieSessionStore;
use actix_web::{web, App, HttpServer};
use actix_web::cookie::Key;
use actix_web::http::StatusCode;
use actix_web::middleware::ErrorHandlers;
use rbatis::snowflake::Snowflake;
use crate::core::permission::user_auth;

#[allow(unused_imports)]
#[macro_use] 
extern crate rust_i18n;

use crate::core::service::{CONTEXT};
use crate::modules::system::controller::open::error_controller::{add_error_body, not_found};
use crate::routes::{open_routes, system_routes, user_routes};
use crate::utils::settings::Settings;

pub mod core;
pub mod utils;
pub mod modules;
pub mod routes;
pub mod plugins;

rust_i18n::i18n!("locales");

pub static SNOWFLAKE: LazyLock<Snowflake> = LazyLock::new(|| {
    Snowflake::new(1,1,1)
});

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let setting = Settings::get();
    log4rs::init_file("./config/log4rs.yaml", Default::default()).unwrap_or_default();

    CONTEXT.init_database().await;
    log::info!("starting HTTP server at https://{:?}",&setting.server.server_url.as_str());
    
    HttpServer::new(move || {
        let cors = Cors::default()
            .allow_any_origin()
            .allowed_methods(vec!["GET", "POST", "PUT", "DELETE"])
            .allowed_headers(vec![header::AUTHORIZATION,
                                  header::ACCEPT, header::ACCESS_CONTROL_ALLOW_ORIGIN])
            .allowed_header(header::CONTENT_TYPE)
            .allow_any_origin()
            .supports_credentials()
            .max_age(3600);
        
        let signing_key = Key::generate();
        let session_mw =
            SessionMiddleware::builder(CookieSessionStore::default(), signing_key.clone())
                .cookie_path(String::from("/"))
                .cookie_name(String::from("token"))
                .cookie_secure(false)
                .session_lifecycle(BrowserSession::default().state_ttl(time::Duration::hours(24)))
                .build();
        
        App::new()
            .wrap(cors)
            .wrap(ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, add_error_body))
            .wrap(user_auth::AuthService)
            .wrap(session_mw)
            .configure(open_routes::configure_routes)
            .configure(user_routes::configure_routes)
            .configure(system_routes::configure_routes)
            .default_service(web::route().to(not_found))
    })
        .bind(&setting.server.server_url)?
        .run()
        .await

}



